package com.itfreer.data.general;

import com.itfreer.data.general.interceptor.DbEditInterceptorClass;
import com.itfreer.data.general.interceptor.DbEditType;
import com.itfreer.data.general.interceptor.DbSelectInterceptorClass;

import java.util.ArrayList;
import java.util.List;

/**
 * 定义提供数据拦截接口处理的表操作基类
 */
public abstract class InterceptorTableBase extends CachedTableBase {

	/**
	 * 执行SQL语句返回查询结果object
	 * 
	 * @param queryMap
	 * @return
	 */
	@Override
	public Object getExecuteScalar(IQueryMap queryMap) {
		Object result = null;
		try {
			DbSelectInterceptorClass.BeforeDbSelectOptionEx(this, queryMap);
			result = super.getExecuteScalar(queryMap);
			DbSelectInterceptorClass.AfterDbSelectOptionEx(this, queryMap, result);
		} catch (Exception e) {
			e.printStackTrace();
			DbSelectInterceptorClass.DbSelectOptionExceptionEx(this,
					queryMap, e);
			throw e;
		}
		return result;
	}

	/**
	 * 将数据绑定到自定义数据类型上
	 * 
	 * @param queryMap
	 * @return
	 */
	@Override
	public <T extends RowBase> List<T> getEntityList(Class<T> c,
			IQueryMap queryMap) {
		List<T> result = null;
		try {
			DbSelectInterceptorClass.BeforeDbSelectOptionEx(this, queryMap);
			result = super.getEntityList(c, queryMap);
			DbSelectInterceptorClass.AfterDbSelectOptionEx(this, queryMap, result);
		} catch (Exception e) {
			e.printStackTrace();
			DbSelectInterceptorClass.DbSelectOptionExceptionEx(this,
					queryMap, e);
			throw e;
		}
		return result;
	}

	/**
	 * 分页查询
	 * 
	 * @param queryMap
	 * @return
	 */
	@Override
	public <T extends RowBase> List<T> pageSelect(Class<T> c,
			IQueryMap queryMap) {
		List<T> result = null;
		try {
			DbSelectInterceptorClass.BeforeDbSelectOptionEx(this, queryMap);
			result = super.pageSelect(c, queryMap);
			DbSelectInterceptorClass.AfterDbSelectOptionEx(this, queryMap, result);
		} catch (Exception e) {
			e.printStackTrace();
			DbSelectInterceptorClass.DbSelectOptionExceptionEx(this,
					queryMap, e);
			throw e;
		}
		return result;
	}

	/**
	 * 更新或添加行
	 * 
	 * @param entity
	 * @return
	 */
	@Override
	public void save(RowBase entity) {
		if (entity == null) {
			return;
		}
		if (entity.getIsNew()) {
			try {
				this.startEditing();
				DbEditInterceptorClass.BeforeDbEditOptionEx(this, entity,
						DbEditType.Insert);
				super.save(entity);
				DbEditInterceptorClass.AfterDbEditOptionEx(this, entity,
						DbEditType.Insert);
				this.stopEditing(true);
			} catch (Exception e) {
				e.printStackTrace();
				DbEditInterceptorClass.DbEditOptionExceptionEx(this, entity,
						DbEditType.Insert, e);
				this.stopEditing(false);
				throw e;
			}
		} else {
			try {
				this.startEditing();
				DbEditInterceptorClass.BeforeDbEditOptionEx(this, entity,
						DbEditType.Update);
				if(!"FS_SAFE_USER".equals(super.getTableName())){// 用户表为物化视图，不可编辑
					super.save(entity);
				}
				DbEditInterceptorClass.AfterDbEditOptionEx(this, entity,
						DbEditType.Update);
				this.stopEditing(true);
			} catch (Exception e) {
				e.printStackTrace();
				DbEditInterceptorClass.DbEditOptionExceptionEx(this, entity,
						DbEditType.Update, e);
				this.stopEditing(false);
				throw e;
			}
		}
	}

	/**
	 * 更新或添加行
	 * 
	 * @param entity
	 * @return
	 */
	@Override
	public <T extends RowBase> void save(List<T> entity) {
		if (entity == null || entity.size() <= 0) {
			return;
		}
		List<T> insertList = new ArrayList<T>();
		List<T> updateList = new ArrayList<T>();
		for (T item : entity) {
			if (item.getIsNew()) {
				insertList.add(item);
			} else {
				updateList.add(item);
			}
		}

		try {
			this.startEditing();
			if (insertList.size() > 0) {
				DbEditInterceptorClass.BeforeDbEditOptionEx(this, insertList,
						DbEditType.Insert);
			}
			if (updateList.size() > 0) {
				DbEditInterceptorClass.BeforeDbEditOptionEx(this, updateList,
						DbEditType.Update);
			}

			super.save(entity);

			if (insertList.size() > 0) {
				DbEditInterceptorClass.AfterDbEditOptionEx(this, insertList,
						DbEditType.Insert);
			}
			if (updateList.size() > 0) {
				DbEditInterceptorClass.AfterDbEditOptionEx(this, updateList,
						DbEditType.Update);
			}

			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			if (insertList.size() > 0) {
				DbEditInterceptorClass.DbEditOptionExceptionEx(this,
						insertList, DbEditType.Insert, e);
			}
			if (updateList.size() > 0) {
				DbEditInterceptorClass.DbEditOptionExceptionEx(this,
						updateList, DbEditType.Update, e);
			}

			this.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 更新或添加行
	 * 
	 * @param entity
	 * @return
	 */
	@Override
	public void insert(RowBase entity) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, entity,
					DbEditType.Insert);
			super.insert(entity);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, entity,
					DbEditType.Insert);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, entity,
					DbEditType.Insert, e);
			this.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 更新或添加行
	 * 
	 * @param entity
	 * @return
	 */
	@Override
	public <T extends RowBase> void insert(List<T> entity) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, entity,
					DbEditType.Insert);
			super.insert(entity);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, entity,
					DbEditType.Insert);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, entity,
					DbEditType.Insert, e);
			this.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 更新或添加行
	 * 
	 * @param entity
	 * @return
	 */
	@Override
	public void update(RowBase entity) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, entity,
					DbEditType.Update);
			super.update(entity);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, entity,
					DbEditType.Update);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, entity,
					DbEditType.Update, e);
			this.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 更新或添加行
	 * 
	 * @param entity
	 * @return
	 */
	@Override
	public <T extends RowBase> void update(List<T> entity) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, entity,
					DbEditType.Update);
			super.update(entity);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, entity,
					DbEditType.Update);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, entity,
					DbEditType.Update, e);
			this.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 更新数据
	 * 
	 * @param updateMap
	 */
	@Override
	public void update(IUpdateMap updateMap) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, updateMap,
					DbEditType.Update);
			super.update(updateMap);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, updateMap,
					DbEditType.Update);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, updateMap,
					DbEditType.Update, e);
			this.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 删除表记录
	 * 
	 * @param queryMap
	 */
	@Override
	public void delete(IQueryMap queryMap) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, queryMap,
					DbEditType.Delete);
			super.delete(queryMap);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, queryMap,
					DbEditType.Delete);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, queryMap,
					DbEditType.Delete, e);
			this.stopEditing(false);
			throw e;
		}
	}

	/**
	 * 删除记录行
	 */
	@Override
	public void delete(String guid) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, guid,
					DbEditType.Delete);
			super.delete(guid);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, guid,
					DbEditType.Delete);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, guid,
					DbEditType.Delete, e);
			this.stopEditing(false);
			throw e;
		}
	}
	
	/**
	 * 删除记录行
	 */
	@Override
	public void delete(List<String> guids) {
		try {
			this.startEditing();
			DbEditInterceptorClass.BeforeDbEditOptionEx(this, guids,
					DbEditType.Delete);
			super.delete(guids);
			DbEditInterceptorClass.AfterDbEditOptionEx(this, guids,
					DbEditType.Delete);
			this.stopEditing(true);
		} catch (Exception e) {
			e.printStackTrace();
			DbEditInterceptorClass.DbEditOptionExceptionEx(this, guids,
					DbEditType.Delete, e);
			this.stopEditing(false);
			throw e;
		}
	}
}